package personal.wang.fileAccess;

import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Objects;

public class FileAccess {

    public long fileWrite(String filePath , String content , boolean isAppend){
        File f = new File(filePath);
        if(!f.getParentFile().exists()){
            f.getParentFile().mkdirs();
        }
        if(!f.exists()){
            try{
                f.createNewFile();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        try(
                OutputStreamWriter isw = new OutputStreamWriter(new FileOutputStream(f , isAppend) , "UTF-8")
        ){
            isw.write(content);
            isw.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0 ;
    }

    public long fileWrite(String filePath, String content, int index) {
        File file = new File(filePath);
        RandomAccessFile randomAccessTargetFile = null;
        MappedByteBuffer map;
        try {
            randomAccessTargetFile = new RandomAccessFile(file, "rw");

            FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
            // map 方法会在内存和 pagecache 之间做一个内存映射
            map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, index, (long) content.getBytes().length);
//            map.position(0);
            map.compact();
            map.put(content.getBytes());
            return map.position();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(!Objects.isNull(randomAccessTargetFile)){
                    randomAccessTargetFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return 0L;
    }

    public static String fileRead(String filePath, long index) {
        File file = new File(filePath);
        System.out.println("file size:" + file.length()/1024 +" kb" + " and read length is " + index/1024);
        RandomAccessFile randomAccessTargetFile = null;
        MappedByteBuffer map;
        try {
            long l = index / 1024;
            int j = 0 ;
            randomAccessTargetFile = new RandomAccessFile(file, "rw");
            FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
            map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, index);
            byte[] byteArr = new byte[1024];

            while (j<l){
                System.out.println("l is " + l + " j is:" + j);
                map.get(byteArr, 0, 1024);
                System.out.println(new String(byteArr,"UTF-8"));
                j++;
            }
            return new String(byteArr,"UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(!Objects.isNull(randomAccessTargetFile)){
                    randomAccessTargetFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public static void main(String[] args) {
        String s = fileRead("D:\\workspace\\part-r-00000", 1024*1024*1024);
        System.out.println(s);
    }
}
